package online.inote.naruto.utils.log;

import online.inote.naruto.utils.Assert;
import online.inote.naruto.utils.StringUtils;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;

import java.util.Objects;

/**
 * @description Logger
 * @author gaopengsui@creditease.cn
 * @date 2021/10/26 10:28 下午
 */
public abstract class Logger {

  private static final String MODULE_SURROUND_BEGIN = "[";
  private static final String MODULE_SURROUND_END = "]";
  private static final String MODULE_SPLIT_STR = ": ";

  private org.slf4j.Logger logger;

  private String module;
  private String message;
  private Object[] arguments;
  private Throwable throwable;

  protected Logger(org.slf4j.Logger logger, String module) {
    Assert.notNull(logger, "logger cannot be null.");
    this.logger = logger;
    this.module = module;
  }

  public Logger module(String module) {
    this.module = module;
    return this;
  }

  public Logger message(String message) {
    this.message = message;
    return this;
  }

  public Logger args(Object... arguments) {
    this.arguments = arguments;
    return this;
  }

  public Logger throwable(Throwable throwable) {
    this.throwable = throwable;
    return this;
  }

  public void print() {
    final FormattingTuple tuple = MessageFormatter.arrayFormat(initMessage(), this.arguments);
    if (Objects.isNull(throwable)) {
      print(tuple.getMessage());
    } else {
      print(tuple.getMessage(), this.throwable);
    }
  }

  private String initMessage() {
    if (!StringUtils.isBlank(this.module)) {
      return this.message;
    }

    return MODULE_SURROUND_BEGIN
        + this.module
        + MODULE_SURROUND_END
        + MODULE_SPLIT_STR
        + this.message;
  }

  /**
   * 输出
   *
   * @param message 消息
   */
  protected abstract void print(String message);

  /**
   * 输出
   *
   * @param message 消息
   * @param throwable 异常
   */
  protected abstract void print(String message, Throwable throwable);

  protected org.slf4j.Logger getLogger() {
    return logger;
  }
}
